package com.zhiche.wms.service.opbaas.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.InterfaceEventEnum;
import com.zhiche.wms.core.supports.enums.NodeOptionEnum;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.core.utils.SnowFlakeId;
import com.zhiche.wms.domain.mapper.opbaas.OpTaskMapper;
import com.zhiche.wms.domain.mapper.opbaas.QrCodeBindMapper;
import com.zhiche.wms.domain.model.opbaas.ExceptionRegister;
import com.zhiche.wms.domain.model.opbaas.OpQrCodeBind;
import com.zhiche.wms.domain.model.opbaas.OpTask;
import com.zhiche.wms.domain.model.opbaas.StatusLog;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.domain.model.sys.SysConfig;
import com.zhiche.wms.domain.model.sys.User;
import com.zhiche.wms.dto.opbaas.paramdto.QrCodeParamDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskDetailResultDTO;
import com.zhiche.wms.service.common.IntegrationService;
import com.zhiche.wms.service.dto.OTMEvent;
import com.zhiche.wms.service.opbaas.IExceptionRegisterService;
import com.zhiche.wms.service.opbaas.IQrCodeBindService;
import com.zhiche.wms.service.opbaas.IStatusLogService;
import com.zhiche.wms.service.otm.IOtmOrderReleaseService;
import com.zhiche.wms.service.sys.IUserService;
import com.zhiche.wms.service.sys.SysConfigService;
import com.zhiche.wms.service.utils.BusinessNodeExport;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 二维码绑定 服务实现类
 * </p>
 *
 * @author user
 * @since 2018-05-24
 */
@Service
public class QrCodeBindServiceImpl extends ServiceImpl<QrCodeBindMapper, OpQrCodeBind> implements IQrCodeBindService {
    @Autowired
    private OpTaskMapper opTaskMapper;
    @Autowired
    private IQrCodeBindService codeBindService;
    @Autowired
    private IExceptionRegisterService registerService;
    @Autowired
    private IOtmOrderReleaseService releaseService;
    @Autowired
    private SnowFlakeId snowFlakeId;
    @Autowired
    private IUserService userService;
    @Autowired
    private BusinessNodeExport nodeExport;
    @Autowired
    private SnowFlakeId flakeId;
    @Autowired
    private IntegrationService integrationService;
    @Autowired
    private IStatusLogService statusLogService;

    @Autowired
    private SysConfigService sysConfigService;
    /**
     * <p>
     * 任务的附码--完成任务   各个节点都能赋码
     * </p>
     *
     * @param dto 参数封装
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void updateBindQrCode(QrCodeParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空");
        }
        dto.setDriverCode(loginUser.getCode());
        dto.setDriverName(loginUser.getName());
        dto.setDriverPhone(loginUser.getMobile());
        String taskId = dto.getTaskId();
        String qrCode = dto.getQrCode();
        String taskType = dto.getTaskType();
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空");
        }
        if (StringUtils.isBlank(qrCode)) {
            throw new BaseException("二维码信息不能为空");
        }
        TaskDetailResultDTO detailDTO;
        if (TableStatusEnum.STATUS_0.getCode().equals(taskType)) {
            //快速附码--关联运单
            detailDTO = bindQuick(dto);
            taskId = dto.getReleaseId();
        } else {
            //通过任务节点绑码
            detailDTO = bindNormal(dto);
        }
        //绑定二维码信息回传otm
        sendQrBindOTM(taskId, qrCode, detailDTO);
    }

    private TaskDetailResultDTO bindQuick(QrCodeParamDTO dto) {
        if (StringUtils.isBlank(dto.getReleaseId())) {
            throw new BaseException("快速附码ReleaseId不能为空");
        }
        //校验二维码是否重复绑定
        EntityWrapper<OtmOrderRelease> ew = new EntityWrapper<>();
        ew.eq("qr_code", dto.getQrCode())
                .ne("status", TableStatusEnum.STATUS_50.getCode());
        int count = releaseService.selectCount(ew);
        if (count > 0) {
            throw new BaseException("该二维码" + dto.getQrCode() + "已经绑定,请确认");
        }
        OtmOrderRelease orderRelease = releaseService.selectById(dto.getReleaseId());
        OpQrCodeBind qrCodeBind = new OpQrCodeBind();
        qrCodeBind.setId(snowFlakeId.nextId());
        qrCodeBind.setWaybillNo(orderRelease.getReleaseGid());
        qrCodeBind.setOmsOrderNo(orderRelease.getCusOrderNo());
        qrCodeBind.setVin(orderRelease.getVin());
        qrCodeBind.setQrCode(dto.getQrCode());
        qrCodeBind.setTaskNode(TableStatusEnum.STATUS_0.getCode());//指令附码节点
        qrCodeBind.setBusinessDoc(String.valueOf(orderRelease.getId()));
        qrCodeBind.setDriverCode(dto.getDriverCode());
        qrCodeBind.setDriverName(dto.getDriverName());
        qrCodeBind.setDriverPhone(dto.getDriverPhone());
        qrCodeBind.setBindTime(new Date());
        qrCodeBind.setStatus(TableStatusEnum.STATUS_10.getCode());
        qrCodeBind.setUserCreate(dto.getDriverCode());
        qrCodeBind.setUserModified(dto.getDriverName());
        qrCodeBind.setGmtCreate(null);
        qrCodeBind.setGmtModified(null);
        codeBindService.insert(qrCodeBind);
        //如果存在多条,更新同车的所有绑定信息
        OtmOrderRelease release = new OtmOrderRelease();
        release.setQrCode(dto.getQrCode());
        EntityWrapper<OtmOrderRelease> reEW = new EntityWrapper<>();
//        reEW.ne("status", TableStatusEnum.STATUS_50.getCode())
//                .eq("vin", orderRelease.getVin());
        reEW.ne("status", TableStatusEnum.STATUS_50.getCode());
        if (StringUtils.isNotBlank(orderRelease.getVin())){
            reEW.eq("vin",orderRelease.getVin());
        }else{
            reEW.eq("release_gid",orderRelease.getReleaseGid());
        }
        releaseService.update(release, reEW);

        TaskDetailResultDTO detailResultDTO = new TaskDetailResultDTO();
        detailResultDTO.setWayBillNo(orderRelease.getReleaseGid());
        detailResultDTO.setDispatchNo(orderRelease.getShipmentGid());
        return detailResultDTO;
    }

    private TaskDetailResultDTO bindNormal(QrCodeParamDTO dto) {
        String taskId = dto.getTaskId();
        String taskType = dto.getTaskType();
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务id不能为空");
        }
        if (StringUtils.isBlank(dto.getQrCode())) {
            throw new BaseException("绑定二维码信息不能为空");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("请登录后进行该操作");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("status50", TableStatusEnum.STATUS_50.getCode());
        params.put("taskType", taskType);
        params.put("taskId", taskId);
        List<TaskDetailResultDTO> detailResultDTOList = opTaskMapper.getTaskDetail(params);
        if (CollectionUtils.isEmpty(detailResultDTOList)) {
            throw new BaseException("未查询到taskId:" + taskId + "的taskType:" + taskType + "信息");
        }
        if (detailResultDTOList.size() > 1) {
            throw new BaseException("查询到taskId:" + taskId + "存在多条任务信息");
        }
        TaskDetailResultDTO detailDTO = detailResultDTOList.get(0);
        //校验二维码是否重复绑定
        EntityWrapper<OtmOrderRelease> ew = new EntityWrapper<>();
        ew.eq("qr_code", dto.getQrCode())
                .ne("status", TableStatusEnum.STATUS_50.getCode());
        int count = releaseService.selectCount(ew);
        if (count > 0) {
            throw new BaseException("该二维码" + dto.getQrCode() + "已经绑定,请确认");
        }
        insertBind(dto, detailDTO);
        //如果存在多个,更新所有同车架号绑定二维码
        OtmOrderRelease release = new OtmOrderRelease();
        release.setQrCode(dto.getQrCode());
        EntityWrapper<OtmOrderRelease> reEW = new EntityWrapper<>();
        reEW.ne("status", TableStatusEnum.STATUS_50.getCode())
                .eq("vin", detailDTO.getVin());
        releaseService.update(release, reEW);

        //更新异常表qrCode
        ExceptionRegister register = new ExceptionRegister();
        register.setUserModified(dto.getDriverCode());
        register.setQrCode(dto.getQrCode());
        EntityWrapper<ExceptionRegister> wrapper = new EntityWrapper<>();
        wrapper.eq("vin", detailDTO.getVin())
                .ne("status", TableStatusEnum.STATUS_0.getCode())
                .eq("oms_order_no", detailDTO.getOrderNo());
        registerService.update(register, wrapper);

        //更新任务状态--可以重新赋码
        OpTask task = new OpTask();
        task.setId(taskId);
        task.setDriverCode(dto.getDriverCode());
        task.setDriverName(dto.getDriverName());
        task.setDriverPhone(dto.getDriverPhone());
        task.setUserModified(dto.getDriverCode());
        //移车任务 提车任务 手动完成(各个环节都能设置赋码,不更新状态)
        if (TableStatusEnum.STATUS_10.getCode().equals(taskType)) {
            //寻车任务直接完成
            task.setStartTime(new Date());
            task.setFinishTime(new Date());
            task.setStatus(TableStatusEnum.STATUS_30.getCode());
            detailDTO.setTaskStatus(TableStatusEnum.STATUS_30.getCode());
            //寻车任务此时完成发送请求到OTM
            sendReOTM(taskId, detailDTO);
            // 调整release 状态为已寻车
            setReleaseAndStatusLog(loginUser, detailDTO);
        }
        HashMap<String,Object> param=new HashMap<>();
        param.put("driverPhone",dto.getDriverPhone());
        param.put("taskType",taskType);
        param.put("status",TableStatusEnum.STATUS_30.getCode());
        param.put("pointId",dto.getPointId());
        sysConfigService.timeConfig(param);
        opTaskMapper.updateById(task);
        return detailDTO;
    }

    private void setReleaseAndStatusLog(User loginUser, TaskDetailResultDTO detailDTO) {
        OtmOrderRelease release = new OtmOrderRelease();
        release.setStatus(TableStatusEnum.STATUS_OR_FIND.getCode());
        release.setId(Long.valueOf(detailDTO.getReleaseId()));
        releaseService.updateById(release);
        StatusLog statusLog = new StatusLog();
        statusLog.setTableType(TableStatusEnum.STATUS_10.getCode());
        statusLog.setTableId(detailDTO.getReleaseId());
        statusLog.setStatus(TableStatusEnum.STATUS_OR_FIND.getCode());
        statusLog.setStatusName(TableStatusEnum.STATUS_OR_FIND.getDetail());
        statusLog.setUserCreate(loginUser.getName());
        statusLogService.insert(statusLog);
    }

    private void sendQrBindOTM(String taskId, String qrCode, TaskDetailResultDTO detailDTO) {
        new Thread(() -> {
            OTMEvent event = integrationService.getOtmEvent(
                    taskId,
                    detailDTO.getWayBillNo(),
                    InterfaceEventEnum.BINDING_CODE.getCode(),
                    detailDTO.getDispatchNo(),
                    "绑定二维码信息回传OTM");
            event.setQrCode(qrCode);
            String res = nodeExport.exportEventToOTM(event);
            if (StringUtils.isNotBlank(res)) {
                integrationService.insertExportLog(
                        taskId,
                        event,
                        res,
                        "绑定二维码信息回传OTM",
                        InterfaceEventEnum.BINDING_CODE.getCode());
            }
        }).start();
    }

    private void insertBind(QrCodeParamDTO dto, TaskDetailResultDTO detailDTO) {
        //插入新的
        OpQrCodeBind codeBind = new OpQrCodeBind();
        codeBind.setId(flakeId.nextId());
        codeBind.setWaybillNo(detailDTO.getWayBillNo());
        codeBind.setOmsOrderNo(detailDTO.getOrderNo());
        codeBind.setVin(detailDTO.getVin());
        codeBind.setQrCode(dto.getQrCode());
        codeBind.setTaskNode(dto.getTaskType());
        codeBind.setBusinessDoc(detailDTO.getTaskId());
        codeBind.setDriverCode(dto.getDriverCode());
        codeBind.setDriverName(dto.getDriverName());
        codeBind.setDriverPhone(dto.getDriverPhone());
        codeBind.setBindTime(new Date());
        codeBind.setStatus(TableStatusEnum.STATUS_10.getCode());
        codeBind.setGmtCreate(null);
        codeBind.setGmtModified(null);
        codeBind.setUserCreate(dto.getDriverCode());
        codeBind.setUserModified(dto.getDriverCode());
        codeBindService.insert(codeBind);
    }

    private void sendReOTM(String taskId, TaskDetailResultDTO detailDTO) {
        new Thread(() -> {
            OTMEvent event = integrationService.getOtmEvent(taskId,
                    detailDTO.getWayBillNo(),
                    InterfaceEventEnum.OR_FIND.getCode(),
                    detailDTO.getDispatchNo(),
                    "完成寻车回传OTM");
            String res = nodeExport.exportEventToOTM(event);
            if (StringUtils.isNotBlank(res)) {
                integrationService.insertExportLog(
                        taskId,
                        event,
                        res,
                        "完成寻车回传OTM",
                        InterfaceEventEnum.OR_FIND.getCode());
            }
        }).start();
    }

}
